unit Checkers.Utils;

interface

uses
  StrUtils,
  SysUtils,
  Classes,
  GLTexture,
  VectorGeometry,
  VectorTypes;

//function StrToInt(const Str: string; Def: Integer = 0): Integer;
//function StrToFloat(const Str: string; Def: Single = 0): Single;

function StringToVector2f(AString: String): TVector2f;
function Vector2fToString(const AVector: TVector2f): String;

function StringToVector3f(AString: String): TVector3f;
function Vector3fToString(const AVector: TVector3f): String;

function StringToVector4f(AString: String): TVector;
function Vector4fToString(const AVector: TVector): String;

procedure StrToVec(const AString: String; var AVector: TVector4f); overload;
procedure StrToVec(const AString: String; var AVector: TVector3f); overload;
procedure StrToVec(const AString: String; var AVector: TVector2f); overload;

function SameStr(const S1, S2: string): Boolean;
function ScreenToOpenGL(const AScreenX, AScreenY, AScreenWidth,
  AScreenHeight: Single): TVector2f;
function VectorToString(const AVector: TVector): String; overload;
function VectorToString(const AVector: TVector4i): String; overload;
function MatrixToString(const AMatrix: TMatrix; ALine: Boolean = True): String;

implementation
{
function StrToInt(const Str: string; Def: Integer = 0): Integer;
var
  Code: Integer;
begin
  Val(Str, Result, Code);
  if Code <> 0 then
    Result := Def;
end;

function StrToFloat(const Str: string; Def: Single = 0): Single;
var
  Code: Integer;
begin
  Val(Str, Result, Code);
  if Code <> 0 then
    Result := Def;
end;
}
function StringToVector2f(AString: String): TVector2f;
var
  A1, A2: Integer;
  F: Single;
  FS: TFormatSettings;
begin
  FS.DecimalSeparator := '.';
  Result := Vector2fMake(0, 0);
  A1 := 1;
  A2 := Pos(',', AString);
  if A2 = 0 then
    Exit;
  if TryStrToFloat(Copy(AString, A1, A2 - A1), F, FS) then
    Result[0] := F;
  A1 := A2 + 1;
  if TryStrToFloat(Copy(AString, A1, Length(AString) + 1 - A1), F, FS) then
    Result[1] := F;
end;

function Vector2fToString(const AVector: TVector2f): String;
begin
  Result := '';
  Result := Result + FloatToStr(AVector[0]) + ',';
  Result := Result + FloatToStr(AVector[1]);
end;

function StringToVector3f(AString: String): TVector3f;
var
  A1, A2: Integer;
  F: Single;
  FS: TFormatSettings;
begin
  FS.DecimalSeparator := '.';
  Result := XYZVector;
  A1 := 1;
  A2 := Pos(',', AString);
  if A2 = 0 then
    Exit;
  if TryStrToFloat(Copy(AString, A1, A2 - A1), F, FS) then
    Result[0] := F;
  A1 := A2 + 1;
  A2 := PosEx(',', AString, A1);
  if A2 = 0 then
    Exit;
  if TryStrToFloat(Copy(AString, A1, A2 - A1), F, FS) then
    Result[1] := F;
  A1 := A2 + 1;
  if TryStrToFloat(Copy(AString, A1, Length(AString) + 1 - A1), F, FS) then
    Result[2] := F;
end;

function Vector3fToString(const AVector: TVector3f): String;
begin
  Result := '';
  Result := Result + FloatToStr(AVector[0]) + ',';
  Result := Result + FloatToStr(AVector[1]) + ',';
  Result := Result + FloatToStr(AVector[2]);
end;

function StringToVector4f(AString: String): TVector;
var
  A1, A2: Integer;
  F: Single;
  FS: TFormatSettings;
begin
  FS.DecimalSeparator := '.';
  Result := XYZWHmgVector;
  A1 := 1;
  A2 := Pos(',', AString);
  if A2 = 0 then
    Exit;
  if TryStrToFloat(Copy(AString, A1, A2 - A1), F, FS) then
    Result[0] := F;
  A1 := A2 + 1;
  A2 := PosEx(',', AString, A1);
  if A2 = 0 then
    Exit;
  if TryStrToFloat(Copy(AString, A1, A2 - A1), F, FS) then
    Result[1] := F;
  A1 := A2 + 1;
  A2 := PosEx(',', AString, A1);
  if A2 = 0 then
    Exit;
  if TryStrToFloat(Copy(AString, A1, A2 - A1), F, FS) then
    Result[2] := F;
  A1 := A2 + 1;
  if TryStrToFloat(Copy(AString, A1, Length(AString) + 1 - A1), F, FS) then
    Result[3] := F;
end;

function Vector4fToString(const AVector: TVector): String;
begin
  Result := '';
  Result := Result + FloatToStr(AVector[0]) + ',';
  Result := Result + FloatToStr(AVector[1]) + ',';
  Result := Result + FloatToStr(AVector[2]) + ',';
  Result := Result + FloatToStr(AVector[3]);
end;

procedure StrToVec(const AString: String; var AVector: TVector4f);
begin
  AVector := StringToVector4f(AString);
end;

procedure StrToVec(const AString: String; var AVector: TVector3f);
begin
  AVector := StringToVector3f(AString);
end;

procedure StrToVec(const AString: String; var AVector: TVector2f);
begin
  AVector := StringToVector2f(AString);
end;


function SameStr(const S1, S2: string): Boolean;
{$IFDEF FPC}
begin
{$ASMMODE intel}
{$ENDIF}
  asm
    CMP     EAX,EDX
    JZ      @1
    OR      EAX,EAX
    JZ      @2
    OR      EDX,EDX
    JZ      @3
    MOV     ECX,[EAX-4]
    CMP     ECX,[EDX-4]
    JNE     @3
    {$IFDEF ALIGN_STACK}
    SUB     ESP, 12
    {$ENDIF ALIGN_STACK}
    CALL    CompareStr
    {$IFDEF ALIGN_STACK}
    ADD     ESP, 12
    {$ENDIF ALIGN_STACK}
    TEST    EAX,EAX
    JNZ     @3
  @1: MOV     AL,1
  @2: RET
  @3: XOR     EAX,EAX
  end;
{$IFDEF FPC}
end;
{$ENDIF}

function ScreenToOpenGL(const AScreenX, AScreenY, AScreenWidth,
  AScreenHeight: Single): TVector2f;
begin
  Result[0] := 2 * AScreenX / AScreenWidth - 1;
  Result[1] := 2 * (1 - AScreenY / AScreenHeight) - 1;
end;

function VectorToString(const AVector: TVector): String;
begin
  Result := '';
  Result := Result + FloatToStr(AVector[0]) + ',';
  Result := Result + FloatToStr(AVector[1]) + ',';
  Result := Result + FloatToStr(AVector[2]) + ',';
  Result := Result + FloatToStr(AVector[3]);
end;

function VectorToString(const AVector: TVector4i): String;
begin
  Result := '';
  Result := Result + IntToStr(AVector[0]) + ',';
  Result := Result + IntToStr(AVector[1]) + ',';
  Result := Result + IntToStr(AVector[2]) + ',';
  Result := Result + IntToStr(AVector[3]);
end;

function MatrixToString(const AMatrix: TMatrix; ALine: Boolean = True): String;
var
  vRowSeparator: String;
begin
  Result := '';
  if ALine then
    vRowSeparator := '; '
  else
    vRowSeparator := #13;
  Result := Result + VectorToString(AMatrix[0]) + vRowSeparator;
  Result := Result + VectorToString(AMatrix[1]) + vRowSeparator;
  Result := Result + VectorToString(AMatrix[2]) + vRowSeparator;
  Result := Result + VectorToString(AMatrix[3]);
end;

end.
